css: Avoid allocations in gtk_css_value_array_compute
authorAlexander Larsson <alexl@redhat.com>
Mon, 3 Dec 2012 13:30:37 +0000 (14:30 +0100)
committerAlexander Larsson <alexl@redhat.com>
Tue, 4 Dec 2012 19:16:44 +0000 (20:16 +0100)
Almost all array computations lead to no changes (99% in nautilus)
so we avoid the upfront allocation and delay it until we know its
needed. This drops the allocate/free from the profile.

gtk/gtkcssarrayvalue.c

index e822619dff74ddcae241415a891bb32df66b47f8..45f1fb2c21e70a61a406e7ad3dd0b699196c3271 100644 (file)
@@ -51,28 +51,33 @@ gtk_css_value_array_compute (GtkCssValue             *value,
                              GtkCssDependencies      *dependencies)
 {
   GtkCssValue *result;
-  gboolean changed = FALSE;
-  guint i;
+  GtkCssValue *i_value;
+  guint i, j;
   GtkCssDependencies child_deps;
 
-  if (value->n_values == 0)
-    return _gtk_css_value_ref (value);
-
-  result = _gtk_css_array_value_new_from_array (value->values, value->n_values);
+  result = NULL;
   for (i = 0; i < value->n_values; i++)
     {
-      result->values[i] = _gtk_css_value_compute (value->values[i], property_id, provider, values, parent_values, &child_deps);
+      i_value =  _gtk_css_value_compute (value->values[i], property_id, provider, values, parent_values, &child_deps);
 
       *dependencies = _gtk_css_dependencies_union (*dependencies, child_deps);
 
-      changed |= (result->values[i] != value->values[i]);
+      if (result == NULL &&
+         i_value != value->values[i])
+       {
+         result = _gtk_css_array_value_new_from_array (value->values, value->n_values);
+         for (j = 0; j < i; j++)
+           _gtk_css_value_ref (result->values[j]);
+       }
+
+      if (result != NULL)
+       result->values[i] = i_value;
+      else
+       _gtk_css_value_unref (i_value);
     }
 
-  if (!changed)
-    {
-      _gtk_css_value_unref (result);
-      return _gtk_css_value_ref (value);
-    }
+  if (result == NULL)
+    return _gtk_css_value_ref (value);
 
   return result;
 }